﻿namespace DesignModeConsole.结构型.享元模式;

/*
假如开发一个棋牌游戏（比如象棋）。一个游戏厅中有成千上万个“房间”，每个房
间对应一个棋局。棋局要保存每个棋子的数据，比如：棋子类型（将、相、士、炮等）、棋
子颜色（红方、黑方）、棋子在棋局中的位置。利用这些数据，我们就能显示一个完整的棋
盘给玩家。具体的代码如下所示。其中，ChessPiece 类表示棋子，ChessBoard 类表示一
个棋局，里面保存了象棋中 30 个棋子的信息。

 */

#region 使用享元之前，充斥大量重复的对象

/// <summary>
/// 棋子类
/// </summary>
public class ChesePiece1
{
    public ChesePiece1(int id, string name, int color, int positinX, int positinY)
    {
        Id = id;
        Name = name;
        Color = color;
        PositinX = positinX;
        PositinY = positinY;
    }

    /// <summary>
    /// 标识
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 棋子名
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 颜色 0代表白色 1代表黑色
    /// </summary>
    public int Color { get; set; }

    /// <summary>
    /// x轴坐标
    /// </summary>
    public int PositinX { get; set; }

    /// <summary>
    /// y轴坐标
    /// </summary>
    public int PositinY { get; set; }
}

/// <summary>
/// 棋局
/// </summary>
public class CheseBoard1
{
    private readonly Dictionary<int, ChesePiece1> dict = new Dictionary<int, ChesePiece1>();

    public CheseBoard1()
    {
    }

    public void Init()
    {
        dict.Add(1, new ChesePiece1(1, "象", 0, 0, 0));
        dict.Add(2, new ChesePiece1(1, "士", 0, 0, 1));
        // 省略其他棋子的写法
    }

    public void Move(int chessPrieceId, int toPositonX, int toPositionY)
    {
        // 移动棋子
    }
}

#endregion

#region 修改为享元对象，将相同的内容拆分出来

/// <summary>
/// 享元类(重复的对象拆分)
/// </summary>
public class ChessPieceUnit
{
    public ChessPieceUnit(int id, string name, int color)
    {
        Id = id;
        Name = name;
        Color = color;
    }

    /// <summary>
    /// 标识
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 棋子名
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 颜色 0代表白色 1代表黑色
    /// </summary>
    public int Color { get; set; }
}

/// <summary>
/// 生产相同棋子属性的工厂
/// </summary>
public static class ChesePieceUnitFactory
{
    private static readonly Dictionary<int, ChessPieceUnit> dict = new Dictionary<int, ChessPieceUnit>();

    static ChesePieceUnitFactory()
    {
        dict.Add(1, new ChessPieceUnit(1, "象", 0));
        dict.Add(2, new ChessPieceUnit(2, "士", 0));
    }

    public static ChessPieceUnit Get(int id)
    {
        return dict[id];
    }
}

/// <summary>
/// 棋子类
/// </summary>
public class ChesePiece2
{
    public ChesePiece2(ChessPieceUnit chessPieceUnit, int positinX, int positinY)
    {
        ChessPieceUnit = chessPieceUnit;
        PositinX = positinX;
        PositinY = positinY;
    }

    public ChessPieceUnit ChessPieceUnit { get; set; }

    /// <summary>
    /// x轴坐标
    /// </summary>
    public int PositinX { get; set; }

    /// <summary>
    /// y轴坐标
    /// </summary>
    public int PositinY { get; set; }
}

/// <summary>
/// 棋局
/// </summary>
public class CheseBoard2
{
    private readonly Dictionary<int, ChesePiece2> dict = new Dictionary<int, ChesePiece2>();

    public CheseBoard2()
    {
        Init();
    }

    public void Init()
    {
        dict.Add(1, new ChesePiece2(ChesePieceUnitFactory.Get(1), 0, 0));
        dict.Add(2, new ChesePiece2(ChesePieceUnitFactory.Get(2), 0, 1));
        // 省略其他棋子的写法
    }

    public void Move(int chessPrieceId, int toPositonX, int toPositionY)
    {
        // 移动棋子
    }
}

#endregion